package com.jyniubi.sms.listener;

import com.jyniubi.sms.service.SmsService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;

@Component
@Slf4j
public class SmsMQListener {
    @Resource
    private SmsService smsService;

    //mq 交换机 队列  绑定的创建方式：   配置类 @Bean ,     注解
    @RabbitListener(bindings = {
            //一个队列和交换机的绑定对象：
            @QueueBinding(
                    value = @Queue(
                            name = "sms.acc.queue",
                            durable = Exchange.TRUE,
                            ignoreDeclarationExceptions = Exchange.TRUE
                    ),
                    exchange = @Exchange(
                            name = "sms.exchange",
                            type = ExchangeTypes.TOPIC,
                            ignoreDeclarationExceptions = Exchange.TRUE
                    ),
                    key = "sms.acc.#"
            )
    })
    public void userAccountListener(Channel channel , Message message, Map<String,String> map) throws IOException {
        try {
            String mobile = map.get("mobile");
            String type = map.get("type");
            String money = map.get("money");
            smsService.sendMessage(mobile,type,money);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            log.info("消息确认异常，消息重新回到队列被再次消费",e);
            if (!message.getMessageProperties().getRedelivered()){
                //2.1 如果是第一次出现异常：让消息重新回到队列 再次消费
                //参数 消息id，事务批量处理 重新归队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }else {
                //2.2 如果消息第二次出现异常：第三次消费仍然失败 丢弃消息(如果绑定了死信队列 该消息会进入到死信队列中)
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }
        }
    }
}
